#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

#include "BuildingException.h"

using namespace std;

enum class type_of_room { Kitchen, Living, Bed, Conference, Business, Workshop, Etc };

std::istream& operator>>(istream& in, type_of_room &t)
{
	string str;
	getline(in, str);
	if (str.compare("Kitchen") == 0)
		t = type_of_room::Kitchen;
	else if (str.compare("Living") == 0)
		t = type_of_room::Living;
	else if (str.compare("Bed") == 0)
		t = type_of_room::Bed;
	else if (str.compare("Conference") == 0)
		t = type_of_room::Conference;
	else if (str.compare("Business") == 0)
		t = type_of_room::Business;
	else if (str.compare("Workshop") == 0)
		t = type_of_room::Workshop;
	else
		t = type_of_room::Etc;
	return in;
}

std::ostream& operator<<(ostream& out, const type_of_room &t)
{
	switch (t)
	{
	case type_of_room::Kitchen: out << "Kitchen"; break;
	case type_of_room::Living: out << "Living";  break;
	case type_of_room::Bed: out << "Bed"; break;
	case type_of_room::Conference: out << "Conference"; break;
	case type_of_room::Business: out << "Business"; break;
	case type_of_room::Workshop: out << "Workshop"; break;
	default: out << "Etc"; break;
	}
	return out;
}

class Room
{

private:
	double area;
	type_of_room type;
public:
	Room()
	{
		area = -1;
		type = type_of_room::Etc;
	}

	Room(double area, type_of_room type)
	{
		if (area <= 0)
		{
			ostringstream oss;
			oss << "Invalid area " << area << " entered for room contructor." << endl;
			oss << "Only positve non-zero numbers are allowed" << endl;
			throw BuildingException(oss.str());
		}
		this->area = area;
		this->type = type;
	}

	~Room(){ }

	void setArea(double area){ this->area = area; }
	void setType(type_of_room type){ this->type = type; }

	double getArea(){ return area; }
	type_of_room getType(){ return type; }

	void Read()
	{
		string str;
		cout << "Area: ";
		getline(cin, str);
		{
			istringstream iss(str);
			iss >> area;
		}
		cout << "Type: ";
		getline(cin, str);
		{
			istringstream iss(str);
			iss >> type;
		}
	}

	void Write()
	{
		cout << "Area: " << area << ", Type: " << type << endl;
	}

	//Dataformat (area,type)
	friend ostream& operator<<(ostream &out, const Room &r)
	{
		out << "(";
		out << r.area << ",";
		out << r.type << ")";
		return out;
	}

	friend istream& operator>>(istream &in, Room &r)
	{
		string str;
		getline(in, str, '(');
		getline(in, str, ',');
		{
			istringstream iss(str);
			iss >> r.area;
		}
		getline(in, str, ')');
		{
			istringstream iss(str);
			iss >> r.type;
		}
		return in;
	}
};

